<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>building_ruby - RDoc Documentation</title>


<script src="../js/navigation.js" defer></script>
<script src="../js/search.js" defer></script>
<script src="../js/search_index.js" defer></script>
<script src="../js/searcher.js" defer></script>
<script src="../js/darkfish.js" defer></script>

<script src="../js/jquery-3.2.0.min.js"></script>

<script src="../js/vue.min.js"></script>
<script src="../js/js.cookie.min.js"></script>

<link href="../css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="../css/rdoc.css" rel="stylesheet">
<link href="../css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "../";
  var index_rel_prefix = "../";
  var darkModeCsseHref = "../css/rdoc-dm.css"
  var defaultModeCssHref = "../css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="file">
  <!-- this is page.html -->
  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0-preview2 NOT FOUND -->
  </div> <!-- end action bar -->


 <div class='wrapper hdiv'>

 


<nav id='vapp' role="navigation">
  <div id="project-navigation">
    <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="../index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="../table_of_contents.html#pages">Pages</a>
    <a href="../table_of_contents.html#classes">Classes</a>
    <a href="../table_of_contents.html#methods">Methods</a>
  </div>
</div>

    <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

  </div>

  
<div class="nav-section">
  <h3>Table of Contents</h3>

  <ul class="link-list" role="directory">
    <li><a href="#label-Building+Ruby">Building Ruby</a>
    <li><a href="#label-Dependencies">Dependencies</a>
    <li><a href="#label-Quick+start+guide">Quick start guide</a>
    <li><a href="#label-Unexplainable+Build+Errors">Unexplainable Build Errors</a>
    <li><a href="#label-More+details">More details</a>
    <li><a href="#label-Running+make+scripts+in+parallel">Running make scripts in parallel</a>
    <li><a href="#label-Miniruby+vs+Ruby">Miniruby vs Ruby</a>
    <li><a href="#label-Debugging">Debugging</a>
    <li><a href="#label-Compiling+for+Debugging">Compiling for Debugging</a>
    <li><a href="#label-Building+with+Address+Sanitizer">Building with Address Sanitizer</a>
    <li><a href="#label-How+to+measure+coverage+of+C+and+Ruby+code">How to measure coverage of C and Ruby code</a>
  </ul>
</div>

  <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>

  <div id="project-metadata">
   <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
    
<div id="fileindex-section" class="nav-section">
  <h3>Pages</h3>

  <ul class="link-list">
    <li><a href="../NEWS/NEWS-1_8_7.html">NEWS-1.8.7</a>
    <li><a href="../NEWS/NEWS-1_9_1.html">NEWS-1.9.1</a>
    <li><a href="../NEWS/NEWS-1_9_2.html">NEWS-1.9.2</a>
    <li><a href="../NEWS/NEWS-1_9_3.html">NEWS-1.9.3</a>
    <li><a href="../NEWS/NEWS-2_0_0.html">NEWS-2.0.0</a>
    <li><a href="../NEWS/NEWS-2_1_0.html">NEWS-2.1.0</a>
    <li><a href="../NEWS/NEWS-2_2_0.html">NEWS-2.2.0</a>
    <li><a href="../NEWS/NEWS-2_3_0.html">NEWS-2.3.0</a>
    <li><a href="../NEWS/NEWS-2_4_0.html">NEWS-2.4.0</a>
    <li><a href="../NEWS/NEWS-2_5_0.html">NEWS-2.5.0</a>
    <li><a href="../NEWS/NEWS-2_6_0.html">NEWS-2.6.0</a>
    <li><a href="../NEWS/NEWS-2_7_0.html">NEWS-2.7.0</a>
    <li><a href="../NEWS/NEWS-3_0_0_md.html">NEWS-3.0.0</a>
    <li><a href="../NEWS/NEWS-3_1_0_md.html">NEWS-3.1.0</a>
    <li><a href="../NEWS/NEWS-3_2_0_md.html">NEWS-3.2.0</a>
    <li><a href="../bsearch_rdoc.html">bsearch</a>
    <li><a href="../bug_triaging_rdoc.html">bug_triaging</a>
    <li><a href="../case_mapping_rdoc.html">case_mapping</a>
    <li><a href="../character_selectors_rdoc.html">character_selectors</a>
    <li><a href="../command_injection_rdoc.html">command_injection</a>
    <li><a href="../contributing_md.html">contributing</a>
    <li><a href="../contributing/building_ruby_md.html">building_ruby</a>
    <li><a href="../contributing/documentation_guide_md.html">documentation_guide</a>
    <li><a href="../contributing/glossary_md.html">glossary</a>
    <li><a href="../contributing/making_changes_to_ruby_md.html">making_changes_to_ruby</a>
    <li><a href="../contributing/making_changes_to_stdlibs_md.html">making_changes_to_stdlibs</a>
    <li><a href="../contributing/reporting_issues_md.html">reporting_issues</a>
    <li><a href="../contributing/testing_ruby_md.html">testing_ruby</a>
    <li><a href="../dig_methods_rdoc.html">dig_methods</a>
    <li><a href="../distribution_md.html">distribution</a>
    <li><a href="../dtrace_probes_rdoc.html">dtrace_probes</a>
    <li><a href="../encodings_rdoc.html">encodings</a>
    <li><a href="../extension_ja_rdoc.html">extension.ja</a>
    <li><a href="../extension_rdoc.html">extension</a>
    <li><a href="../fiber_md.html">fiber</a>
    <li><a href="../format_specifications_rdoc.html">format_specifications</a>
    <li><a href="../globals_rdoc.html">globals</a>
    <li><a href="../implicit_conversion_rdoc.html">implicit_conversion</a>
    <li><a href="../keywords_rdoc.html">keywords</a>
    <li><a href="../maintainers_md.html">maintainers</a>
    <li><a href="../marshal_rdoc.html">marshal</a>
    <li><a href="../memory_view_md.html">memory_view</a>
    <li><a href="../optparse/argument_converters_rdoc.html">argument_converters</a>
    <li><a href="../optparse/creates_option_rdoc.html">creates_option</a>
    <li><a href="../optparse/option_params_rdoc.html">option_params</a>
    <li><a href="../optparse/tutorial_rdoc.html">tutorial</a>
    <li><a href="../packed_data_rdoc.html">packed_data</a>
    <li><a href="../ractor_md.html">ractor</a>
    <li><a href="../regexp_rdoc.html">regexp</a>
    <li><a href="../regexp/methods_rdoc.html">methods</a>
    <li><a href="../regexp/unicode_properties_rdoc.html">unicode_properties</a>
    <li><a href="../ruby_3_3_0_preview2/COPYING.html">COPYING</a>
    <li><a href="../ruby_3_3_0_preview2/COPYING_ja.html">COPYING.ja</a>
    <li><a href="../ruby_3_3_0_preview2/LEGAL.html">LEGAL</a>
    <li><a href="../ruby_3_3_0_preview2/NEWS_md.html">NEWS</a>
    <li><a href="../ruby_3_3_0_preview2/README_ja_md.html">README.ja</a>
    <li><a href="../ruby_3_3_0_preview2/README_md.html">README</a>
    <li><a href="../security_rdoc.html">security</a>
    <li><a href="../signals_rdoc.html">signals</a>
    <li><a href="../standard_library_rdoc.html">standard_library</a>
    <li><a href="../strftime_formatting_rdoc.html">strftime_formatting</a>
    <li><a href="../syntax_rdoc.html">syntax</a>
    <li><a href="../syntax/assignment_rdoc.html">assignment</a>
    <li><a href="../syntax/calling_methods_rdoc.html">calling_methods</a>
    <li><a href="../syntax/comments_rdoc.html">comments</a>
    <li><a href="../syntax/control_expressions_rdoc.html">control_expressions</a>
    <li><a href="../syntax/exceptions_rdoc.html">exceptions</a>
    <li><a href="../syntax/literals_rdoc.html">literals</a>
    <li><a href="../syntax/methods_rdoc.html">methods</a>
    <li><a href="../syntax/miscellaneous_rdoc.html">miscellaneous</a>
    <li><a href="../syntax/modules_and_classes_rdoc.html">modules_and_classes</a>
    <li><a href="../syntax/pattern_matching_rdoc.html">pattern_matching</a>
    <li><a href="../syntax/precedence_rdoc.html">precedence</a>
    <li><a href="../syntax/refinements_rdoc.html">refinements</a>
    <li><a href="../timezones_rdoc.html">timezones</a>
    <li><a href="../windows_md.html">windows</a>
    <li><a href="../yjit/yjit_md.html">yjit</a>
    <li><a href="../yjit/yjit_hacking_md.html">yjit_hacking</a>
  </ul>
</div>

   </div>
  </div>
</nav>


<!--  carbon ads here -->

<div id='extraz'>
  <div class='adzbox-index'  >
   
  </div>
 </div>         


<main role="main" aria-label="Page contributing/building_ruby.md">

<h1 id="label-Building+Ruby">Building Ruby<span><a href="#label-Building+Ruby">&para;</a> <a href="#top">&uarr;</a></span></h1>

<h2 id="label-Dependencies">Dependencies<span><a href="#label-Dependencies">&para;</a> <a href="#top">&uarr;</a></span></h2>
<ol><li>
<p>Install the prerequisite dependencies for building the CRuby interpreter:</p>
<ul><li>
<p>C compiler</p>
</li></ul>

<p>For RubyGems, you will also need:</p>
<ul><li>
<p>OpenSSL 1.1.x or 3.0.x / LibreSSL</p>
</li><li>
<p>libyaml 0.1.7 or later</p>
</li><li>
<p>zlib</p>
</li></ul>

<p>If you want to build from the git repository, you will also need:</p>
<ul><li>
<p>autoconf - 2.67 or later</p>
</li><li>
<p>gperf - 3.1 or later</p>
<ul><li>
<p>Usually unneeded; only if you edit some source files using gperf</p>
</li></ul>
</li><li>
<p>ruby - 2.5 or later</p>
<ul><li>
<p>We can upgrade this version to system ruby version of the latest Ubuntu LTS.</p>
</li></ul>
</li></ul>
</li><li>
<p>Install optional, recommended dependencies:</p>
<ul><li>
<p>libffi (to build fiddle)</p>
</li><li>
<p>gmp (if you with to accelerate Bignum operations)</p>
</li><li>
<p>libexecinfo (FreeBSD)</p>
</li><li>
<p>rustc - 1.58.0 or later, if you wish to build  <a href="https://docs.ruby-lang.org/en/master/RubyVM/YJIT.html">YJIT</a>.</p>
</li></ul>

<p>If you installed the libraries needed for extensions (openssl, readline, libyaml, zlib) into other than the OS default place, typically using Homebrew on macOS, add <code>--with-EXTLIB-dir</code> options to <code>CONFIGURE_ARGS</code> environment variable.</p>

<pre>export CONFIGURE_ARGS=&quot;&quot;
for ext in openssl readline libyaml zlib; do
  CONFIGURE_ARGS=&quot;${CONFIGURE_ARGS} --with-$ext-dir=$(brew --prefix $ext)&quot;
done</pre>
</li></ol>

<h2 id="label-Quick+start+guide">Quick start guide<span><a href="#label-Quick+start+guide">&para;</a> <a href="#top">&uarr;</a></span></h2>
<ol><li>
<p>Download ruby source code:</p>

<p>Select one of the bellow.</p>
<ol><li>
<p>Build from the tarball:</p>

<p>Download the latest tarball from <a href="https://www.ruby-lang.org/en/downloads/">ruby-lang.org</a> and extract it. Example for Ruby 3.0.2:</p>

<pre>tar -xzf ruby-3.0.2.tar.gz
cd ruby-3.0.2</pre>
</li><li>
<p>Build from the git repository:</p>

<p>Checkout the CRuby source code:</p>

<pre>git clone https://github.com/ruby/ruby.git
cd ruby</pre>

<p>Generate the configure file:</p>

<pre>./autogen.sh</pre>
</li></ol>
</li><li>
<p>Create a <code>build</code> directory separate from the source directory:</p>

<pre>mkdir build &amp;&amp; cd build</pre>

<p>While it's not necessary to build in a separate directory, it's good practice to do so.</p>
</li><li>
<p>We'll install Ruby in <code>~/.rubies/ruby-master</code>, so create the directory:</p>

<pre>mkdir ~/.rubies</pre>
</li><li>
<p>Run configure:</p>

<pre>../configure --prefix=&quot;${HOME}/.rubies/ruby-master&quot;</pre>
<ul><li>
<p>If you are frequently building Ruby, add the <code>--disable-install-doc</code> flag to not build documentation which will speed up the build process.</p>
</li></ul>
</li><li>
<p>Build Ruby:</p>

<pre class="ruby"><span class="ruby-identifier">make</span> <span class="ruby-identifier">install</span>
</pre>
</li><li>
<p><a href="testing_ruby_md.html">Run tests</a> to confirm your build succeeded.</p>
</li></ol>

<h3 id="label-Unexplainable+Build+Errors">Unexplainable Build Errors<span><a href="#label-Unexplainable+Build+Errors">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>If you are having unexplainable build errors, after saving all your work, try running <code>git clean -xfd</code> in the source root to remove all git ignored local files. If you are working from a source directory that's been updated several times, you may have temporary build artifacts from previous releases which can cause build failures.</p>

<h2 id="label-More+details">More details<span><a href="#label-More+details">&para;</a> <a href="#top">&uarr;</a></span></h2>

<p>If you're interested in continuing development on Ruby, here are more details about Ruby's build to help out.</p>

<h3 id="label-Running+make+scripts+in+parallel">Running make scripts in parallel<span><a href="#label-Running+make+scripts+in+parallel">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>In GNU make and BSD make implementations, to run a specific make script in parallel, pass the flag <code>-j&lt;number of processes&gt;</code>. For instance, to run tests on 8 processes, use:</p>

<pre>make test-all -j8</pre>

<p>We can also set <code>MAKEFLAGS</code> to run <em>all</em> <code>make</code> commands in parallel.</p>

<p>Having the right <code>--jobs</code> flag will ensure all processors are utilized when building software projects. To do this effectively, you can set <code>MAKEFLAGS</code> in your shell configuration/profile:</p>

<pre># On macOS with Fish shell:
export MAKEFLAGS=&quot;--jobs &quot;(sysctl -n hw.ncpu)

# On macOS with Bash/ZSH shell:
export MAKEFLAGS=&quot;--jobs $(sysctl -n hw.ncpu)&quot;

# On Linux with Fish shell:
export MAKEFLAGS=&quot;--jobs &quot;(nproc)

# On Linux with Bash/ZSH shell:
export MAKEFLAGS=&quot;--jobs $(nproc)&quot;</pre>

<h3 id="label-Miniruby+vs+Ruby">Miniruby vs Ruby<span><a href="#label-Miniruby+vs+Ruby">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>Miniruby is a version of Ruby which has no external dependencies and lacks certain features. It can be useful in Ruby development because it allows for faster build times. Miniruby is built before Ruby. A functional Miniruby is required to build Ruby. To build Miniruby:</p>

<pre class="ruby"><span class="ruby-identifier">make</span> <span class="ruby-identifier">miniruby</span>
</pre>

<h2 id="label-Debugging">Debugging<span><a href="#label-Debugging">&para;</a> <a href="#top">&uarr;</a></span></h2>

<p>You can use either lldb or gdb for debugging. Before debugging, you need to create a <code>test.rb</code> with the Ruby script you’d like to run. You can use the following make targets:</p>
<ul><li>
<p><code>make run</code>: Runs <code>test.rb</code> using Miniruby</p>
</li><li>
<p><code>make lldb</code>: Runs <code>test.rb</code> using Miniruby in lldb</p>
</li><li>
<p><code>make gdb</code>: Runs <code>test.rb</code> using Miniruby in gdb</p>
</li><li>
<p><code>make runruby</code>: Runs <code>test.rb</code> using Ruby</p>
</li><li>
<p><code>make lldb-ruby</code>: Runs <code>test.rb</code> using Ruby in lldb</p>
</li><li>
<p><code>make gdb-ruby</code>: Runs <code>test.rb</code> using Ruby in gdb</p>
</li></ul>

<h3 id="label-Compiling+for+Debugging">Compiling for Debugging<span><a href="#label-Compiling+for+Debugging">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>You should configure Ruby without optimization and other flags that may interfere with debugging:</p>

<pre>./configure --enable-debug-env optflags=&quot;-O0 -fno-omit-frame-pointer&quot;</pre>

<h3 id="label-Building+with+Address+Sanitizer">Building with Address Sanitizer<span><a href="#label-Building+with+Address+Sanitizer">&para;</a> <a href="#top">&uarr;</a></span></h3>

<p>Using the address sanitizer is a great way to detect memory issues.</p>

<pre>./autogen.sh
mkdir build &amp;&amp; cd build
export ASAN_OPTIONS=&quot;halt_on_error=0:use_sigaltstack=0:detect_leaks=0&quot;
../configure cppflags=&quot;-fsanitize=address -fno-omit-frame-pointer&quot; optflags=-O0 LDFLAGS=&quot;-fsanitize=address -fno-omit-frame-pointer&quot;
make</pre>

<p>On Linux it is important to specify <code>-O0</code> when debugging. This is especially true for ASAN which sometimes works incorrectly at higher optimisation levels.</p>

<h2 id="label-How+to+measure+coverage+of+C+and+Ruby+code">How to measure coverage of C and Ruby code<span><a href="#label-How+to+measure+coverage+of+C+and+Ruby+code">&para;</a> <a href="#top">&uarr;</a></span></h2>

<p>You need to be able to use gcc (gcov) and lcov visualizer.</p>

<pre>./autogen.sh
./configure --enable-gcov
make
make update-coverage
rm -f test-coverage.dat
make test-all COVERAGE=true
make lcov
open lcov-out/index.html</pre>

<p>If you need only C code coverage, you can remove <code>COVERAGE=true</code> from the above process. You can also use <code>gcov</code> command directly to get per-file coverage.</p>

<p>If you need only Ruby code coverage, you can remove <code>--enable-gcov</code>. Note that <code>test-coverage.dat</code> accumulates all runs of <code>make test-all</code>. Make sure that you remove the file if you want to measure one test run.</p>

<p>You can see the coverage result of CI: <a href="https://rubyci.org/coverage">rubyci.org/coverage</a></p>

</main>

</div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>. </p><p><a href="https://jamesbritt.bandcamp.com/">Hack your world.  Feed your head.  Live curious</a>.</p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

